package model.dominio;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.PostPersist;
import javax.persistence.PostUpdate;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import model.dao.DaoBase;

/**
 * 
 * @author Daniel
 * Classe responsável pelos objetos de Perfil do Usuario.
 * Abaixo, temos os annotations para configuração do banco de dados em JPA, utilizando o Hibernate.
 */
@Entity
@Table(name = "perfil_usuario")
public class PerfilUsuario implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(unique = true, nullable = false)
    private Integer codigo;
    @Column(length = 100)
    private String nome;
    @OneToMany(mappedBy = "perfil")
    private List<Usuario> usuarios = new ArrayList<Usuario>();
    @ManyToMany(targetEntity = model.dominio.AcaoSistema.class, cascade = {CascadeType.PERSIST, CascadeType.MERGE}, fetch = FetchType.EAGER)
    @JoinTable(name = "perfil_acao", joinColumns = {
        @JoinColumn(name = "codigo_perfil")}, inverseJoinColumns = {
        @JoinColumn(name = "codigo_acao")})
    private List<AcaoSistema> permissoes = new ArrayList<AcaoSistema>();
    @Temporal(TemporalType.TIMESTAMP)
    private Calendar data_ultima_alteracao;
    @JoinColumn(name = "codigo_usuario", referencedColumnName = "codigo")
    @ManyToOne(optional = true, fetch = FetchType.EAGER, cascade = CascadeType.PERSIST)
    private Usuario usuario;

    /**
     * @return nome do Perfil
     */
    public String getNome() {
        return nome;
    }

    /**
     * @param nome do Perfil para ser setado
     */
    public void setNome(String nome) {
        this.nome = nome;
    }

    /**
     * @return lista de usuarios cadastrados
     */
    public List<Usuario> getUsuarios() {
        return usuarios;
    }

    /**
     * @param usuario para ser adicionado a lista destes
     */
    public void addUsuario(Usuario usuario) {
        this.usuarios.add(usuario);
    }

    /**
     * 
     * @return lista de permissoes existentes no banco de dados
     */
    public List<AcaoSistema> getPermissoes() {
        return permissoes;
    }

    /**
     * 
     * @return codigo do Perfil de Usuário
     */
    public Integer getCodigo() {
        return codigo;
    }

    /**
     * @param permissao a ser adicionada a Lista de Permissões 
     */
    public void addPermissoes(AcaoSistema permissao) {
        this.permissoes.add(permissao);
    }

    /**
     * Sobrescrita do método toString().
     * @return nome do objeto Perfil de Usuário instanciado no momento
     */
    @Override
    public String toString() {
        return this.nome;
    }

    /**
     * Sobrescrita do método equals().
     * @param obj
     * Verificado se é uma instância de PerfilUsuario para uso correto
     * @return codigo do Perfil de Usuario ou false
     */
    @Override
    public boolean equals(Object obj) {
        if (obj instanceof PerfilUsuario) {
            PerfilUsuario p = (PerfilUsuario) obj;
            return this.codigo.equals(p.getCodigo());
        } else {
            return false;
        }
    }

    /**
     * @param codigo setado automaticamente para cada Perfil de Usuário.
     */
    public void setCodigo(Integer codigo) {
        this.codigo = codigo;
    }

    public void setUsuario(Usuario usuarioLogado) {
        this.usuario = usuarioLogado;
    }

    public void setData_ultima_alteracao(Calendar data) {
        this.data_ultima_alteracao = data;
    }

    @PostPersist
    public void gerarLogCad() {
        Logg logg = new Logg();
        logg.setCodigo_objeto(this.codigo);
        logg.setAcao(new AcaoSistema(24));
        logg.setData_hora(this.data_ultima_alteracao);
        logg.setUsuario(this.usuario);
        new DaoBase().salvar(logg);
    }

    @PostUpdate
    public void gerarLogAlt() {
        Logg logg = new Logg();
        logg.setCodigo_objeto(this.codigo);
        logg.setAcao(new AcaoSistema(25));
        logg.setData_hora(this.data_ultima_alteracao);
        logg.setUsuario(this.usuario);
        new DaoBase().salvar(logg);
    }
}
